package com.googlecode.textish.parser;

import java.util.List;

import com.googlecode.textish.tokenizer.IContainerToken;
import com.googlecode.textish.tokenizer.IToken;

/**
 * Decorates a {@link IContainerToken} with methods to aid parsing.
 * 
 * @author cgdavies
 * 
 */
public class ContainerTokenDecorator implements IContainerToken {

	private int m_startDelta;

	private int m_endDelta;

	private boolean m_dirty;

	private IContainerToken m_wrappedToken;

	public ContainerTokenDecorator(IContainerToken wrappedToken) {
		m_wrappedToken = wrappedToken;
	}

	/**
	 * Increases the value of {@link #getStartIndex()}, effectively chomping a
	 * token from the beginning of the list of contained tokens.
	 */
	public void chompStart() {
		chompStart(1);
	}

	/**
	 * Increases the value of {@link #getStartIndex()} by <code>amount</code>,
	 * effectively chomping <code>amount</code> tokens from the beginning of
	 * the list of contained tokens.
	 * 
	 * @param amount the number of tokens to chomp from the beginning of the
	 * child list
	 */
	public void chompStart(int amount) {
		if (amount < 1)
			throw new IllegalArgumentException("amount must be greater than 0.");

		m_startDelta += amount;
		setDirty(true);
	}

	/**
	 * Decreases the value of {@link #getEndIndex()}, effectively chomping a
	 * token from the end of the list of contained tokens.
	 */
	public void chompEnd() {
		chompEnd(1);
	}

	/**
	 * Decreases the value of {@link #getEndIndex()} by <code>amount</code>,
	 * effectively chomping <code>amount</code> tokens from the end of the
	 * list of contained tokens.
	 * 
	 * @param amount the number of tokens to chomp from the end of the child
	 * list
	 */
	public void chompEnd(int amount) {
		if (amount < 1)
			throw new IllegalArgumentException("amount must be greater than 0.");

		m_endDelta += amount;
		setDirty(true);
	}

	public void setDirty(boolean dirty) {
		m_dirty = dirty;
	}

	/**
	 * @return <code>true</code> if any chomp methods were called since the
	 * dirty-flag was last set to <code>false</code>
	 */
	public boolean isDirty() {
		return m_dirty;
	}

	public int getStartIndex() {
		return ((IToken) m_wrappedToken.getChildTokens().get(m_startDelta)).getStartIndex();
	}

	public int getEndIndex() {
		List childTokens = m_wrappedToken.getChildTokens();
		return ((IToken) childTokens.get(childTokens.size() - m_endDelta - 1)).getEndIndex();
	}

	public List getChildTokens() {
		List wrappedChildTokens = m_wrappedToken.getChildTokens();
		return wrappedChildTokens.subList(m_startDelta, wrappedChildTokens.size() - m_endDelta);
	}

}
